import { Rect } from './common';
import theme from './theme';

export default class Scrollbar {
    /**
     * @param args {ctx, type, rect, style, clientHeight, clientWidth, scrollWidth, scrollHeight} 
     */
    constructor(args) {
        this.position = 0;
        Object.assign(this, args);
        if (this.style) {
            Object.keys(this.style).forEach(key => {
                if (this.style[key] === undefined) {
                    delete this.style[key];
                }
            })
        }
        this.style = {
            foregroundColor: theme.SCROLL_FOREGROUND_COLOR,
            backgroundColor: theme.SCROLL_BACKGROUND_COLOR,
            cornerColor: theme.SCROLL_CORNER_COLOR,
            ...(this.style || {}),
        }
        this.barRect = new Rect(0,0,0,0);
        this._scrollLeft = 0;
        this._scrollTop = 0;
    }
    testIn(x, y) {
        if (this.rect.testIn(x, y)) {
            if (this.barRect.testIn(x, y)) {
                return 2;
            }
            return 1;
        }
        return 0;
    }
    draw() {
        const {ctx, type, rect, style, scrollWidth, clientWidth, scrollHeight, clientHeight, _scrollTop, _scrollLeft} = this;
        ctx.save();
        ctx.translate(0,0);
        ctx.fillStyle = style.backgroundColor;
        ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
        ctx.fillStyle = style.foregroundColor;
        if (type === Scrollbar.HOR) {
            const w = this.rect.w * clientWidth / scrollWidth;
            const x = _scrollLeft * this.rect.w / scrollWidth;
            ctx.fillRect(x + rect.x, rect.y, w, rect.h);
            this.barRect = new Rect(x + rect.x, rect.y, w, rect.h);
        } else {
            const h = this.rect.h * clientHeight / scrollHeight;
            const y = _scrollTop * this.rect.h / scrollHeight;
            ctx.fillRect(rect.x, y + rect.y, rect.w, h);
            this.barRect = new Rect(rect.x, y + rect.y, rect.w, h);
        }
        ctx.restore();
    }
    /**
     * setPosition
     */
    setPosition(x, y) {
        const { scrollHeight, scrollWidth, clientHeight, clientWidth } = this;
        if (this.type === Scrollbar.HOR) {
            let barX;
            if (x - this.rect.x > this.rect.w - this.barRect.w) {
                barX = this.rect.w - this.barRect.w;
            } else {
                const n = Math.floor((x - this.rect.x) / this.barRect.w);
                barX = n * this.barRect.w;
            }
            const left = barX * scrollWidth / this.rect.w;
            this.scrollLeft = left;
            return left;
        } else {
            let barY;
            if (y - this.rect.y > this.rect.h - this.barRect.h) {
                barY = this.rect.h - this.barRect.h;
            } else {
                const n = Math.floor((y - this.rect.y) / this.barRect.h);
                barY = n * this.barRect.h;
            }
            const top = barY * scrollHeight / this.rect.h;
            this.scrollTop = top;
            return top;
        }
    }
    set scrollTop(value) {
        this._scrollTop = value;
        this.draw();
    }
    set scrollLeft(value) {
        this._scrollLeft = value;
        this.draw();
    }
    get horizontalPixelRatio() {
        return (this.scrollWidth - this.clientWidth) / (this.rect.w - this.barRect.w);
    }
    get verticalPixelRatio() {
        return (this.scrollHeight - this.clientHeight) / (this.rect.h - this.barRect.h);
    }
}

Scrollbar.HOR = 1;
Scrollbar.VER = 2;